﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;

namespace Anagramme.Contracts
{
    /// <summary>
    /// Contrat pour le service de lobby
    /// </summary>
    [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ILobbyServiceCallback))]
    public interface ILobbyService
    {
        /// <summary>
        /// Envoie d'une demande pour changer le mode de jeu
        /// </summary>
        /// <param name="gameMode">Nouveau mode de jeu</param>
        /// <remarks>Nécessite d'être le maitre du lobby</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyChangeGameMode(GameModes gameMode);

        /// <summary>
        /// Envoie d'une demande pour changer la longueur maximale des mots
        /// </summary>
        /// <param name="length">Nouvelle longueur maximale des mots</param>
        /// <remarks>Nécessite d'être le maitre du lobby</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyChangeMaxWordsLength(int length);

        /// <summary>
        /// Envoie d'une demande pour changer la longueur minimale des mots
        /// </summary>
        /// <param name="length">Nouvelle longueur minimale des mots</param>
        /// <remarks>Nécessite d'être le maitre du lobby</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyChangeMinWordsLength(int length);

        /// <summary>
        /// Envoie d'une demande pour changer le nombre de rounds cible
        /// </summary>
        /// <param name="targetRounds">Nouveau nombre de rounds cible</param>
        /// <remarks>Nécessite d'être le maitre du lobby</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyChangeTargetRounds(int targetRounds);

        /// <summary>
        /// Envoie d'une demande pour changer le score cible
        /// </summary>
        /// <param name="targetScore">Nouveau score cible</param>
        /// <remarks>Nécessite d'être le maitre du lobby</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyChangeTargetScore(int targetScore);

        /// <summary>
        /// Envoie d'une demande d'extinction du serveur
        /// </summary>
        /// <remarks>Nécessite d'être le maitre du lobby</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyClose();

        /// <summary>
        /// Envoie d'une demande pour récupérer les informations sur le serveur
        /// </summary>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyInfos();

        /// <summary>
        /// Indique que le statut "Prêt" à été modifié
        /// </summary>
        /// <param name="isReady">Nouveau statut "Prêt"</param>
        /// <remarks>Vaut True si le joueur est prêt, sinon False</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyIsReadyToPlay(bool isReady);

        /// <summary>
        /// Envoie d'une demande pour rejoindre la partie
        /// </summary>
        /// <param name="userName">Nom du joueur</param>
        /// <remarks>Cette méthode est la première à appeler sur le serveur, car elle renvoie le jeton de sécurité nécessaire à tout les autres appels</remarks>
        [OperationContract(IsOneWay = true, IsInitiating = true)]
        void RequestLobbyJoin(string userName);

        /// <summary>
        /// Indique au serveur que le joueur quitte le lobby
        /// </summary>
        [OperationContract(IsOneWay = true, IsTerminating = true)]
        void RequestLobbyLeave();

        /// <summary>
        /// Envoie d'une demande de chargement de la partie
        /// </summary>
        /// <remarks>Cette demande est propagée aux autres joueurs</remarks>
        /// <remarks>Nécessite d'être le maitre du lobby</remarks>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyLoadGame();
        
        /// <summary>
        /// Envoie d'une demande pour récupérer les informations sur le joueur
        /// </summary>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyPlayerInfo();

        /// <summary>
        /// Envoie d'une demande pour récupérer la liste des joueurs de la partie
        /// </summary>
        [OperationContract(IsOneWay = true)]
        void RequestLobbyPlayers();
    }
}
